home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Hot Mix 17
/
Hot Mix 17.iso
/
HM17_SGI
/
research
/
lib
/
obsolete
/
widalloc.pro
< prev
next >
Wrap
Text File
|
1997-07-08
|
9KB
|
296 lines
;
; $Id: widalloc.pro,v 1.9 1997/01/15 03:11:50 ali Exp $
;
; WidAlloc
; Widget Editor allocation related routines.
;
; Copyright (c) 1993-1997, Research Systems, Inc. All rights reserved.
; Unauthorized reproduction prohibited.
;
; MODIFICATION HISTORY
; Written by: Joshua Goldstein, 12/93
;
;
; Destroy
; Generic function to cause an object to delete itself from memory.
; This is assumed to be recursive (objects containing other objects
; should destroy their children as well).
;
PRO Destroy, Ptr
; An invalid pointer is considered to be already destroyed
; Not much we could do anyway.
IF WIDGET_INFO(Ptr, /VALID_ID) EQ 0 THEN RETURN
; Figure out the class specific routine name and call it
GetType, Ptr, Type
CALL_PROCEDURE,Type+"_Destroy",Ptr
END
;
; GenDestroy
; Generic Object destruction routine.
;
PRO GenDestroy, Ptr, HASVALUE=HasValue
Ptr2Obj, Ptr, Obj
IF N_ELEMENTS(Obj) EQ 0 THEN RETURN
IF KEYWORD_SET(HasValue) THEN $
WIDGET_CONTROL, Obj.Value1, /DESTROY ; Destroy value contents
IF WIDGET_INFO(Obj.Dialog, /VALID) THEN $ ; Destroy dialog box
WIDGET_CONTROL, Obj.Dialog, /DESTROY
WIDGET_CONTROL, Ptr, /DESTROY ; Release pointer memory
; Object is in local variable and goes away as we return
END
;
; GenCopy
; Copy an object. 2 copy methods:
;
; if( copy != NULL) { *copy = *ptr; free(ptr); }
; else { *(copy = malloc(...)) = *ptr; }
;
PRO GenCopy, Ptr, Copy, HASVALUE=HasValue
COMMON WidEd_Comm
IF KEYWORD_SET(Copy) THEN BEGIN ; Copy is already allocated
Ptr2Obj, Copy, ThrowAway ; Release current copy contents
IF KEYWORD_SET(HasValue) THEN $
WIDGET_CONTROL, ThrowAway.Value1, /DESTROY ; Destroy value too
Ptr2Obj, Ptr, Obj ; Remove object from original pointer
Obj2Ptr, Obj, Copy ; Store in copy pointer
WIDGET_CONTROL, Ptr, /DESTROY ; Release original pointer memory
ENDIF ELSE BEGIN
Ptr2Obj, Ptr, Obj, /COPY ; Make a copy of ptr contents
IF KEYWORD_SET(HasValue) THEN $
Ptr2Obj, Obj.Value1, Value1, /COPY ; Get copy of value1 contents
Copy = WIDGET_BASE(GROUP=TopDlg) ; Make a new pointer
IF KEYWORD_SET(HasValue) THEN BEGIN
Obj.Value1 = WIDGET_BASE(GROUP=TopDlg) ; New ptr for value
IF N_ELEMENTS(Value1) NE 0 THEN $
Obj2Ptr, Value1, Obj.Value1 ; Save value
ENDIF
Obj.Id = NewId()
Obj2Ptr, Obj, Copy ; Store copy into new pointer
ENDELSE
END
;
; Ptr2Obj
; Pointers are really unrealized base widget objects and the
; contents are their UVALUEs. In general, copying structures is
; an expensive operation so the default is to REMOVE the UVALUE
; from the pointer. This is much faster. Note that is has the
; side effect that the pointer is no longer valid (has no object
; in it).
;
PRO Ptr2Obj, Ptr, Obj, COPY=Copy
WIDGET_CONTROL, Ptr, GET_UVALUE=Obj, NO_COPY=(1 - KEYWORD_SET(Copy))
END
;
; Obj2Ptr
; The reverse of Ptr2Obj. Place the given object (as a UVALUE) into
; the given pointer (unrealized base widget). Copy the value if
; explicitly requested, otherwise the Object given us will no longer
; contain a value upon return from this function.
;
PRO Obj2Ptr, Obj, Ptr, COPY=Copy
WIDGET_CONTROL, Ptr, SET_UVALUE=Obj, NO_COPY=(1 - KEYWORD_SET(Copy))
END
;
; NextPtr
; Returned the contents of the .Next field of an object. All objects
; must have a .Next field.
;
FUNCTION NextPtr, Ptr
Ptr2Obj, Ptr, Obj
Next = Obj.Next
Obj2Ptr, Obj, Ptr
RETURN, Next
END
;
; AddChild
; Add an object to a base object.
;
; NO_UPDATE -- If set, DONT call the routine to update the Cut/Copy/Paste
; dialog boxes. Set when adding multiple objects (as in File Open)
;
; NO_CANCEL -- If set the object is not added to the Active dialog
; list. This is done for base objects (Base Object Dialog boxes
; have no CANCEL button) and should be done for any object class
; which can not/should not be removed.
;
PRO AddChild, Parent, Child, NO_UPDATE=NoUpdate, NO_CANCEL=NoCancel
COMMON WidEd_Comm
; Set Parent Ptr in child
SetTag, Child, "Parent", Parent
; Get the Parent object structure
Ptr2Obj, Parent, PObj
; First Child ? Set parent child list.
; Else last child in list now has a next child
;
IF PObj.Children EQ 0 THEN PObj.Children = Child $
ELSE SetTag, PObj.LastChild, "Next", Child
; Remember the last child
PObj.LastChild = Child
Obj2Ptr, PObj, Parent ; Restore structure into parent pointer
; Add to active dialog list so we can delete it in the event
; user CANCELs addition.
IF KEYWORD_SET(NoCancel) EQ 0 THEN BEGIN
NewDialogs = [ NewDialogs, { WE_NEWOBJ, Parent, Child, 0L } ]
ENDIF
; Update Cut/Copy/Paste/Edit Dialog boxes
IF KEYWORD_SET(NoUpDate) EQ 0 THEN UpdateEdit
; Note that the object tree has been altered.
Dirty = 1
END
;
; Cancel
; Common routine to handle the 'CANCEL' button on dialog boxes.
; This performs 2 separate actions depending upon what has happened
; so far:
;
; If the object has been added but never realized (no Rebuild) then
; OldPtr is NULL and there is no state to revert the widget to.
; Otherwise, we have a copy of the widgets previous state and we
; restore it instead of deleting it.
;
; Note: The object information has already been pulled out of the pointer
; so we need both to be passed in.
;
PRO Cancel, Obj, Ptr
COMMON WidEd_Comm
Type = Obj.Type ; Get the type
Dialog = Obj.Dialog ; Get the Dialog Box widget Id.
Obj2Ptr, Obj, Ptr ; Stick Object back into pointer so that
; other routines can access object via its ptr
; See if this object can be cancelled. Should always be found.
; In fact we display an error message if we don't
Idx = WHERE(NewDialogs.ObjPtr EQ Ptr, Count)
IF Count NE 1 THEN ErrorDialog, TopDlg, $
"Internal Error: CANCEL'ed widget could not be found"
; Do we have an previous version of this widget to revert to?
Idx = Idx[0]
IF NewDialogs[Idx].OldPtr NE 0L THEN BEGIN
; Call class specific copy routine to revert object to
; its previous state: *ObjPtr = *OldPtr
CALL_PROCEDURE, Type + "_Copy", NewDialogs[Idx].OldPtr, $
NewDialogs[Idx].ObjPtr
WIDGET_CONTROL, Dialog, /DESTROY ; Take down dialog box
ENDIF ELSE BEGIN
; This is more difficult. Remove the object from its
; parent's list of children
ParPtr = NewDialogs[Idx].ParPtr ; Get Parent Object
Ptr2Obj, ParPtr, ParObj
; Is it the first child?
IF ParObj.Children EQ Ptr THEN BEGIN
ParObj.Children = NextPtr(Ptr)
; Was it an only child?
IF ParObj.LastChild EQ Ptr THEN ParObj.LastChild = ParObj.Children
ENDIF ELSE BEGIN
PrevPtr = ParObj.Children ; Run down the list of children
CurrPtr = NextPtr(PrevPtr) ; until we find the child in
NxtPtr = NextPtr(Ptr) ; question. Keep track of the
WHILE CurrPtr NE Ptr DO BEGIN ; previous child.
PrevPtr = CurrPtr
CurrPtr = NextPtr(CurrPtr)
ENDWHILE
; Unlink the deleted child from the list of children
; If it was the last child of the parent object then set
; the LastChild field to the new last child.
SetTag, PrevPtr, "Next", NxtPtr
IF ParObj.LastChild EQ Ptr THEN ParObj.LastChild = PrevPtr
ENDELSE
Obj2Ptr, ParObj, ParPtr ; Restore Parent pointer
; The child has been removed from the object tree. Delete
; the child.
CALL_PROCEDURE, Type + "_Destroy", Ptr ; Destroy Object
ENDELSE
; Now we have to remove the deleted object from the list
; of objects with active dialog boxes.
N = N_ELEMENTS(NewDialogs)
IF Idx[0] EQ N-1 THEN $ ; Last active object?
NewDialogs = NewDialogs[0:N-2] $
ELSE $
NewDialogs = [ NewDialogs[0:Idx-1], NewDialogs[Idx+1,*] ]
UpdateEdit
END
;
; Accept
; The user has pressed the 'DONE' button or just closed the dialog
; box via the window manager menu Close option. Unfortunately these
; look like 'DONE's and not 'CANCEL's. Thats what documentation is for.
;
; Note: as with Cancel, the Object structure is already outside of
; the pointer
; Unlike Cancel, Base Objects also need to be handled (not that
; this makes any difference here)
;
PRO Accept, Obj, Ptr
Obj2Ptr, Obj, Ptr ; Stick Object back into pointer
END
PRO WidAlloc
END